package com.imooc.sell.service.impl;

import com.imooc.sell.dao.ProductInfoDao;
import com.imooc.sell.dataobject.ProductCategory;
import com.imooc.sell.dataobject.ProductInfo;
import com.imooc.sell.dataobject.query.ProductQuery;
import com.imooc.sell.enums.enumUtils.EnumUtil;
import com.imooc.sell.service.ProductInfoService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.imooc.sell.enums.SortEnum.SORT_BYCATEGORY_ASC;
import static com.imooc.sell.enums.SortEnum.SORT_BYID_ASC;


/**
 * 商品管理业务实现类
 */
@Service
public class ProductInfoServiceImpl implements ProductInfoService {

    @Autowired
    ProductInfoDao productInfoDao;

    @Override
    public ProductInfo findOne(String productId) {
        return productInfoDao.getOne(productId);
    }

    @Override
    public List<ProductInfo> findAll() {
        return productInfoDao.findAll();
    }

    @Override
    public Page<ProductInfo> findAll(Pageable pageable) {
        return productInfoDao.findAll(pageable);
    }

    @Override
    public ProductInfo save(ProductInfo productInfo) {
        ProductInfo productInfo1;
        try {
            if (productInfo.getId() == null) {
                productInfo1 = productInfoDao.save(productInfo);
            } else {
                ProductInfo productInfo2 = productInfoDao.getOne(productInfo.getId());
                BeanUtils.copyProperties(productInfo, productInfo2);
                productInfo1 = productInfoDao.save(productInfo2);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return productInfo1;
    }

    @Override
    public Boolean delete(String id) {
        try {
            productInfoDao.deleteById(id);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    @Override
    @Transactional
    public Boolean deleteByCategoryType(Integer id) {
        try {
            productInfoDao.deleteByCategoryType(id);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    @Override
    public Page<ProductInfo> findProductCrCriteria(Integer page, Integer size, ProductQuery productQuery, Integer sortCode) {

        Page<ProductInfo> productPage = productInfoDao.findAll(new Specification<ProductInfo>() {
            @Override
            public Predicate toPredicate(Root<ProductInfo> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                List<Predicate> list = new ArrayList<Predicate>();
                if (null != productQuery.getId() && !"".equals(productQuery.getId())) {
                    list.add(criteriaBuilder.equal(root.get("id").as(String.class), productQuery.getId()));
                }
                Predicate[] p = new Predicate[list.size()];
                return criteriaBuilder.and(list.toArray(p));
            }
        }, EnumUtil.getPageable(page, size, sortCode));
        return productPage;

    }

    @Override
    public Page<ProductInfo> findProductByTime(Date createTime, Date endTime, Integer page, Integer size) {
        Pageable pageable = new PageRequest(page, size, Sort.Direction.ASC, "createTime");
        Page<ProductInfo> productInfoPage = productInfoDao.findAll(new Specification<ProductInfo>() {
            @Nullable
            @Override
            public Predicate toPredicate(Root<ProductInfo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> list = new ArrayList<Predicate>();
                try {
                    if (createTime != null && endTime != null) {
                        list.add(criteriaBuilder.between(root.get("createTime"),
                                createTime,
                                endTime));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                Predicate[] p = new Predicate[list.size()];
                return criteriaBuilder.and(list.toArray(p));
            }
        }, pageable);
        return productInfoPage;
    }
}
